﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using SageKing.Core.Extensions;

namespace SageKing.Core.Service;

/// <summary>
/// 通用CRUD接口服务
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TKey"></typeparam>
public abstract class CrudBaseApiResourceServicei<TEntity, TKey> : ICRUDBaseApi<TEntity, TKey>, IHttpClientAuthorization
{

    /// <summary>
    /// 当前API接口地址
    /// </summary>
    public abstract string ApiEndpoint { get; set; }

    public readonly HttpClient _httpClient;
    public readonly IOpenIddictToken _openIddictToken;

    public CrudBaseApiResourceServicei(IHttpClientFactory httpClientFactory,
        IOpenIddictToken openIddictToken)
    {
        _httpClient = httpClientFactory.CreateClient(HttpClientConsts.HttpClientResourceEndPointUrlKey) ?? throw new ArgumentNullException(nameof(httpClientFactory));
        _openIddictToken = openIddictToken;
        //await InitAuthorizationToken();
    }

    #region Token
    public string Token { get; private set; }

    public virtual bool AddAuthorizationToken(string token, bool addBearer = true)
    {
        this.Token = token;
        if (_httpClient.DefaultRequestHeaders.Contains(HttpClientConsts.HeaderAuthKey))
        {
            _httpClient.DefaultRequestHeaders.Remove(HttpClientConsts.HeaderAuthKey);
        }

        var tmpBearer = (addBearer ? HttpClientConsts.HeaderAuthBearer : "") + token;
        _httpClient.DefaultRequestHeaders.Add(HttpClientConsts.HeaderAuthKey, tmpBearer);
        return true;
    }

    public virtual async Task InitAuthorizationToken(bool isClear = false)
    {
        if (Token.IsNullOrEmpty() || isClear)
        {
            Token = await _openIddictToken.GetTokenWithClientCredentialsAsync();
            AddAuthorizationToken(Token);
        }
    }


    #endregion
    #region CRUD

    public virtual async Task<SageKingResult<PageBase<TEntity>>> GetPageAsync(PageBaseInput page)
    {
        var response = await _httpClient.PostAsJsonAsync($"{ApiEndpoint}/page", page);
        return await CheckStatusCode<PageBase<TEntity>>(response);
    }

    public virtual async Task<SageKingResult<TEntity>> GetAsync(TKey id)
    {
        var response = await _httpClient.GetAsync($"{ApiEndpoint}/{id}");

        return await CheckStatusCode<TEntity>(response);
    }

    public virtual async Task<SageKingResult<TKey>> CreateAsync(TEntity model)
    {
        var response = await _httpClient.PostAsJsonAsync(ApiEndpoint, model);

        return await CheckStatusCode<TKey>(response);
    }

    public virtual async Task<SageKingResult<bool>> DeleteAsync(TKey id)
    {
        var response = await _httpClient.DeleteAsync($"{ApiEndpoint}/{id}");

        return await CheckStatusCode<bool>(response);
    }


    public virtual async Task<SageKingResult<bool>> UpdateAsync(TEntity model)
    {
        var response = await _httpClient.PutAsJsonAsync(ApiEndpoint, model);

        return await CheckStatusCode<bool>(response);
    }

    #endregion


    public virtual async Task<SageKingResult<TResult>> CheckStatusCode<TResult>(HttpResponseMessage response, bool IsEnsureSuccessStatusCode = false)
    {
        switch (response.StatusCode)
        {
            case HttpStatusCode.NotFound:
                return new SageKingResult<TResult>().NotFound("请求错误: 404 NotFound", (int)response.StatusCode);
            default:
                break;
        }

        if (IsEnsureSuccessStatusCode)
        {
            response.EnsureSuccessStatusCode();
        }
        //统一返回格式 
        var result = await response.Content.ReadFromJsonAsync<SageKingResult<TResult>>();
        return result;
    }
}
